<template>
  <div class="board-container">
    <el-card class="control-panel" shadow="never">
      <el-row :gutter="20" justify="space-between" align="middle">
        <el-col :xs="24" :sm="12" :md="10" :lg="8">
          <div class="station-selector">
            <span>选择工位:</span>
            <el-select
                v-model="selectedStation"
                placeholder="请选择一个工位"
                @change="handleStationChange"
                style="width: 100%; max-width: 280px; margin-left: 10px;"
                filterable
            >
              <el-option
                  v-for="item in stationOptions"
                  :key="item.id"
                  :label="`${item.id}号工位 (${item.name})`"
                  :value="item.id"
              />
            </el-select>
          </div>
        </el-col>
        <el-col :xs="24" :sm="12" :md="14" :lg="16" class="actions-col">
          <div class="actions">
            <el-button type="primary" :icon="Refresh" @click="fetchQueue(true)" :loading="loading">刷新列表</el-button>
            <el-button type="success" :icon="Promotion" @click="handleSchedule" :loading="scheduleLoading">
              执行智能调度
            </el-button>
          </div>
        </el-col>
      </el-row>
    </el-card>

    <div class="queue-area" v-loading="loading">
      <el-empty v-if="!selectedStation || queue.length === 0"
                :description="!selectedStation ? '请先选择一个工位以查看队列' : '当前工位队列为空'"/>

      <draggable
          v-else
          v-model="queue"
          class="queue-list"
          item-key="dispatchId"
          animation="500"
          ghost-class="ghost-card"
          @end="handleDragEnd"
          :disabled="isAnyTaskActive"
      >
        <template #item="{ element: item }">
          <div
              class="queue-card"
              :class="{
                  'processing': item.status === 2,
                  'paused': item.status === 4
              }"
          >
            <div class="card-header">
              <div class="product-info">
                <el-tag effect="dark" size="small" style="margin-right: 8px;">{{ item.queueId }}</el-tag>
                <span class="product-name">{{ item.productName }}</span>
                <span class="product-type">{{ item.productType }}</span>
              </div>
              <el-tag :type="getTagType(item.status)" effect="light">
                {{ item.statusText }}
              </el-tag>
            </div>
            <div class="card-body">
              <div class="info-item">
                <el-icon><Tickets/></el-icon>
                <span>工件ID:
                  <el-link type="primary" @click="showLifecycle(item.pieceId)">{{ item.pieceId }}</el-link>
                </span>
              </div>
              <div class="info-item">
                <el-icon><Timer/></el-icon>
                <span>标准耗时: {{ item.elapsed }} 分钟</span>
              </div>
            </div>

            <div v-if="item.status === 2 || item.status === 4" class="progress-section">
              <el-progress
                  :percentage="item.progressPercentage || 0"
                  :stroke-width="10"
                  :color="item.progressColor"
                  striped
                  striped-flow
              >
                <template #default>
                  <span class="progress-text">{{ item.displayText || '0%' }}</span>
                </template>
              </el-progress>
              <div class="time-display">
                <span>实际用时 / 标准用时</span>
                <span>{{ item.netProcessingMinutes || 0 }} / {{ item.elapsed }} 分钟</span>
              </div>
            </div>

            <div class="card-actions">
              <el-button v-if="item.status === 1" type="primary" :icon="VideoPlay" @click="handleStart(item.dispatchId)"
                         :disabled="isAnyTaskProcessing || item.queueId !== 1" plain>
                启动加工
              </el-button>

              <el-button v-if="item.status === 2" type="warning" :icon="VideoPause"
                         @click="handlePause(item.dispatchId)" plain>
                暂停加工
              </el-button>

              <el-button v-if="item.status === 4" type="primary" :icon="CaretRight"
                         @click="handleResume(item.dispatchId)" plain>
                继续加工
              </el-button>

              <el-button
                  v-if="item.status === 2 || item.status === 4"
                  :type="item.status === 2 ? 'success' : 'info'"
                  :icon="Select"
                  @click="handleComplete(item.dispatchId)"
                  :disabled="item.status === 4"
                  plain>
                完成加工
              </el-button>
            </div>

          </div>
        </template>
      </draggable>
    </div>

    <el-drawer
        v-model="drawerVisible"
        :title="`工件 ${currentPieceId} 的生命周期追踪`"
        direction="rtl"
        size="500px"
    >
      <div v-loading="lifecycleLoading" style="padding: 0 20px;">
        <el-timeline v-if="lifecycleData.length > 0">
          <el-timeline-item
              v-for="(activity, index) in lifecycleData"
              :key="index"
              :timestamp="activity.timestamp"
              :type="activity.statusText === '完成加工' ? 'success' : 'primary'"
              :hollow="true"
          >
            <h4>{{ activity.statusText }}</h4>
            <p>工序: {{ activity.processName }}</p>
            <p>工位: {{ activity.workstationName }}</p>
          </el-timeline-item>
        </el-timeline>
        <el-empty v-else description="暂无生命周期记录"></el-empty>
      </div>
    </el-drawer>
  </div>
</template>

<script setup>
import {ref, onMounted, onBeforeUnmount, computed} from 'vue'
import {useRoute} from 'vue-router'
import draggable from 'vuedraggable'
import {useWorkstationBoardStore} from '@/store/modules/workstationBoard'
import {useConfigStore} from '@/store/modules/config' // [新增] 引入Config Store
import {getAllWorkstations} from '@/api/modules/workstation'
import {
  getWorkstationQueue,
  schedulePieces,
  startProcessing,
  completeProcessing,
  getPieceLifecycle,
  pauseProcessing,
  resumeProcessing,
  reorderWorkstationQueue
} from '@/api/modules/dispatch'
import {ElMessage, ElNotification} from 'element-plus'
import {
  Refresh, Promotion, Tickets, Timer, VideoPlay, Select,
  VideoPause, CaretRight
} from '@element-plus/icons-vue'

const loading = ref(false)
const scheduleLoading = ref(false)
const stationOptions = ref([])
const queue = ref([])
const autoRefreshTimer = ref(null)
const drawerVisible = ref(false)
const lifecycleLoading = ref(false)
const lifecycleData = ref([])
const currentPieceId = ref('')
const progressTimer = ref(null);

const route = useRoute();
const boardStore = useWorkstationBoardStore();
const configStore = useConfigStore();

const updateProgress = () => {
  // 从store获取动态配置
  const warningThreshold = Number(configStore.getConfigValue('alert.zone.warning_percent', 10));
  const alertThreshold = Number(configStore.getConfigValue('alert.zone.alert_percent', 20));
  const speedMultiplier = Number(configStore.getConfigValue('dev.time.speed_multiplier', 1)); // 获取倍速

  queue.value.forEach(item => {
    if (item.status === 2 && item.startTime) {
      // 1. 计算真实世界的已用秒数
      const start = new Date(item.startTime.replace(/-/g, '/')).getTime();
      const now = new Date().getTime();
      const realElapsedSeconds = Math.floor((now - start) / 1000);
      const totalPausedSeconds = item.totalPausedSeconds || 0;
      const netRealElapsedSeconds = Math.max(0, realElapsedSeconds - totalPausedSeconds);

      // 2. 应用倍速，计算出模拟的加工秒数
      const simulatedProcessingSeconds = netRealElapsedSeconds * speedMultiplier;

      // 3. 后续所有计算都基于这个“模拟秒数”
      const standardSeconds = item.elapsed * 60;
      const rawPercentage = (standardSeconds > 0) ? (simulatedProcessingSeconds / standardSeconds) * 100 : 0;

      const deviation = Math.abs(rawPercentage - 100);
      if (deviation > alertThreshold) {
        item.progressColor = '#F56C6C';
      } else if (deviation > warningThreshold) {
        item.progressColor = '#E6A23C';
      } else {
        item.progressColor = '#67C23A';
      }

      item.rawPercentage = rawPercentage;
      item.isOverdue = rawPercentage >= 100;
      // 这里的分钟数也基于模拟秒数，所以它会飞速增长
      item.netProcessingMinutes = Math.floor(simulatedProcessingSeconds / 60);
      item.progressPercentage = parseFloat(Math.min(100, rawPercentage).toFixed(2));

      if (item.isOverdue) {
        item.displayText = '已超时';
      } else {
        item.displayText = `${rawPercentage.toFixed(0)}%`;
      }
    }
  });
};

const fetchQueue = async (isInitialLoad = false) => {
  if (!selectedStation.value) return;
  if (isInitialLoad) loading.value = true;
  try {
    const newQueueData = await getWorkstationQueue(selectedStation.value);
    const existingItemsMap = new Map(queue.value.map(item => [item.dispatchId, item]));

    // 保留旧对象引用，只更新数据，避免UI闪烁
    newQueueData.forEach(newItem => {
      if(existingItemsMap.has(newItem.dispatchId)) {
        Object.assign(existingItemsMap.get(newItem.dispatchId), newItem);
      } else {
        queue.value.push(newItem);
      }
    });

    // 移除已不存在的项
    const newItemsSet = new Set(newQueueData.map(item => item.dispatchId));
    queue.value = queue.value.filter(item => newItemsSet.has(item.dispatchId));

    // 保持排序
    queue.value.sort((a,b) => a.queueId - b.queueId);

  } catch (error) {
    console.error("获取工位队列失败", error);
    queue.value = [];
  } finally {
    if (isInitialLoad) loading.value = false;
  }
};

const selectedStation = computed({
  get: () => boardStore.selectedStationId,
  set: (val) => boardStore.setSelectedStation(val)
});

const isAnyTaskActive = computed(() => queue.value.some(task => task.status === 2 || task.status === 4));
const isAnyTaskProcessing = computed(() => queue.value.some(task => task.status === 2));

const fetchStationOptions = async () => {
  try {
    stationOptions.value = await getAllWorkstations();
    const initialWsid = route.query.wsid;
    if (initialWsid && stationOptions.value.some(s => s.id === initialWsid)) {
      boardStore.setSelectedStation(initialWsid);
    }
    if (selectedStation.value) {
      await fetchQueue(true);
      startAutoRefresh();
    }
  } catch (error) {
    console.error("获取工位列表失败", error);
  }
};

const startAutoRefresh = () => {
  if (autoRefreshTimer.value) clearInterval(autoRefreshTimer.value);
  autoRefreshTimer.value = setInterval(() => {
    if (selectedStation.value && !loading.value) {
      fetchQueue(false);
    }
  }, 10000);
};

const handleStationChange = (wsid) => {
  fetchQueue(true);
  startAutoRefresh();
};

const handleSchedule = async () => {
  scheduleLoading.value = true;
  try {
    const results = await schedulePieces();
    if (results && results.length > 0) {
      const resultHtml = results.map(r => `<div>工件 <strong>${r.pieceId}</strong> 已分配到 <strong>${r.workstationId}号工位 (${r.workstationName})</strong></div>`).join('');
      ElNotification({
        title: '调度成功！',
        dangerouslyUseHTMLString: true,
        message: `<div style="max-height: 200px; overflow-y: auto; font-size: 12px;">${resultHtml}</div>`,
        type: 'success',
        duration: 0
      });
    } else {
      ElMessage.info('没有需要调度的新工件。');
    }
    if (selectedStation.value) {
      setTimeout(() => fetchQueue(true), 500);
    }
  } catch (error) {
    console.error("调度失败", error);
  } finally {
    scheduleLoading.value = false;
  }
};

const handleStart = async (dispatchId) => {
  try {
    await startProcessing(dispatchId);
    ElMessage.success('工件已启动！');
    await fetchQueue(true);
  } catch (error) {
    console.error('启动失败', error);
  }
};

const handlePause = async (dispatchId) => {
  try {
    await pauseProcessing(dispatchId);
    ElMessage.warning('工件已暂停！');
    await fetchQueue(true);
  } catch (error) {
    console.error('暂停失败', error);
  }
};

const handleResume = async (dispatchId) => {
  try {
    await resumeProcessing(dispatchId);
    ElMessage.success('工件已恢复加工！');
    await fetchQueue(true);
  } catch (error) {
    console.error('恢复失败', error);
  }
};

const handleComplete = async (dispatchId) => {
  const warningThreshold = Number(configStore.getConfigValue('alert.zone.warning_percent', 10));
  const alertThreshold = Number(configStore.getConfigValue('alert.zone.alert_percent', 20));

  const completedItem = queue.value.find(item => item.dispatchId === dispatchId);
  let finalStatus = '正常';
  let finalColor = 'success';

  if (completedItem && completedItem.rawPercentage !== undefined) {
    const deviation = Math.abs(completedItem.rawPercentage - 100);
    if (deviation > alertThreshold) {
      finalStatus = completedItem.isOverdue ? '严重超时' : '严重提前';
      finalColor = 'error';
    } else if (deviation > warningThreshold) {
      finalStatus = completedItem.isOverdue ? '略有延后' : '略有提前';
      finalColor = 'warning';
    }
  }

  try {
    const nextStop = await completeProcessing(dispatchId);
    let message = `工件已完成！(绩效: ${finalStatus})`
    if (nextStop) {
      message += ` 已自动调度至 [${nextStop.workstationId}号工位]`;
    }

    ElMessage({
      type: finalColor,
      message: message,
      duration: 5000
    });

    await fetchQueue(true);
  } catch (error) {
    console.error('完成失败', error);
  }
};

const showLifecycle = async (pieceId) => {
  currentPieceId.value = pieceId;
  drawerVisible.value = true;
  lifecycleLoading.value = true;
  try {
    lifecycleData.value = await getPieceLifecycle(pieceId);
  } catch (error) {
    console.error("获取生命周期失败", error);
    lifecycleData.value = [];
  } finally {
    lifecycleLoading.value = false;
  }
};

const getTagType = (status) => {
  switch (status) {
    case 1: return 'info';
    case 2: return 'success';
    case 4: return 'warning';
    default: return 'primary';
  }
};

const handleDragEnd = async () => {
  const reorderedPayload = queue.value.map((task, index) => {
    task.queueId = index + 1;
    return {
      dispatchId: task.dispatchId,
      newQueueId: task.queueId
    };
  });
  try {
    await reorderWorkstationQueue(reorderedPayload);
    ElMessage.success('队列顺序已保存！');
  } catch (error) {
    console.error('顺序保存失败！', error);
    ElMessage.error('顺序保存失败，将刷新以恢复。');
    setTimeout(() => fetchQueue(true), 1500);
  }
};

onMounted(async () => {
  // [修改] 确保配置在加载工位列表前被获取
  await configStore.fetchConfigs();
  fetchStationOptions();

  if (progressTimer.value) clearInterval(progressTimer.value);
  progressTimer.value = setInterval(updateProgress, 1000);
});

onBeforeUnmount(() => {
  if (autoRefreshTimer.value) clearInterval(autoRefreshTimer.value);
  if (progressTimer.value) clearInterval(progressTimer.value);
});
</script>

<style scoped>
.board-container {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 90px - 40px);
}

.control-panel {
  margin-bottom: 20px;
  flex-shrink: 0;
}

.control-panel :deep(.el-card__body) {
  padding: 15px 20px;
}

.station-selector {
  display: flex;
  align-items: center;
  font-size: 14px;
  justify-content: flex-start;
}

.actions-col {
  display: flex;
  justify-content: flex-end;
}

.actions {
  display: flex;
  justify-content: flex-end;
}

@media (max-width: 768px) {
  .actions-col {
    justify-content: flex-start;
    margin-top: 15px;
  }
}

.queue-area {
  flex-grow: 1;
  overflow-y: auto;
  padding: 5px;
}

.queue-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
  gap: 20px;
}

/* --- 卡片样式 --- */
.queue-card {
  background-color: #fff;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .05);
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.queue-card.processing {
  border-left: 5px solid #67C23A;
}

.queue-card.paused {
  border-left: 5px solid #E6A23C;
}

.card-header {
  padding-bottom: 15px; display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-body {
  padding-top: 15px;
  padding-bottom: 15px;
  border-top: 1px solid #f0f2f5;
  flex-grow: 1;
}

.progress-section {
  padding-top: 15px;
  padding-bottom: 15px;
  border-top: 1px solid #f0f2f5;
}

.card-actions {
  padding-top: 15px;
  border-top: 1px solid #f0f2f5;
  margin-top: auto;
}

.progress-section + .card-actions {
  border-top: none;
}

.product-info .product-name {
  font-size: 16px; font-weight: bold;
  color: #303133;
}
.product-info .product-type {
  font-size: 12px;
  color: #909399;
  margin-left: 8px;
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  font-size: 14px;
  color: #606266;
}
.info-item:last-child {
  margin-bottom: 0;
}

.info-item .el-icon {
  margin-right: 8px;
  color: #909399;
}

.info-item .el-link {
  font-size: 13px;
}

.time-display {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.progress-section :deep(.el-progress-bar__inner) {
  transition: width 0.6s ease !important;
}

.card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.ghost-card {
  opacity: 0.5;
  background: #c8ebfb;
  border: 1px dashed #409EFF;
  border-radius: 8px;
}

.queue-card:active {
  cursor: grabbing !important;
  transform: scale(0.98);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}

:deep(.queue-list[disabled='true'] .queue-card) {
  cursor: not-allowed;
}

:deep(.queue-list[disabled='true'] .queue-card:active) {
  cursor: not-allowed;
  transform: none;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .05);
}

.card-actions :deep(.el-button.is-disabled),
.card-actions :deep(.el-button.is-disabled:hover) {
  background-color: #f5f7fa !important;
  border-color: #e4e7ed !important;
  color: #c0c4cc !important;
  cursor: default !important;
}

.progress-text {
  font-size: 14px;
  margin-left: 10px;
}
</style>
